// AI助手的node js文件

const express = require('express');
const { exec } = require('child_process');
const cors = require('cors');  // 需要安装 cors 包
const http = require('http');
const OpenAI = require('openai');
const app = express();

// 创建OpenAI实例
const openai = new OpenAI({
  baseURL: "http://localhost:11434/v1",  // Ollama API地址
  apiKey: "ollama"  // 任意值即可，Ollama不验证
});

// 更新CORS配置支持动态来源
const allowedOrigins = [
  'https://wx.yijianhealth.com',
  /^http:\/\/localhost(:\d+)?$/, // 匹配所有本地开发地址
  /^http:\/\/192.168.110.186(:\d+)?$/, // 匹配所有本地开发地址
  'https://23917dm6pj31.vicp.fun' // 生产环境地址
]

// 启用 CORS
app.use(cors({
  origin: (origin, callback) => {
    // 允许无来源请求（如postman）
    if (!origin) return callback(null, true)

    if (allowedOrigins.some(pattern => {
      if (typeof pattern === 'string') {
        return origin === pattern
      }
      return pattern.test(origin)
    })) {
      return callback(null, true)
    }

    return callback(new Error('请求来源未被允许'))
  },
  methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
  allowedHeaders: ['Content-Type', 'Authorization'],
  credentials: true
}));

// 中间件处理 JSON
app.use(express.json());

// 添加推荐提示词配置
const recommendPrompts = { // 推荐提示词对象
  default: [ // 默认提示词
    "您好，我能为您做什么？",
    "需要我为您解答什么问题？",
    "有什么可以帮您的吗？"
  ],
  report: [ // 检验报告相关提示词
    "请帮我分析这份检验报告的异常项",
    "这些检验指标对身体健康有什么影响",
    "如何改善这些异常指标",
    "请给出相关的饮食建议"
  ]
};

// 检查 Ollama API
function checkOllamaAPI() {
  return new Promise((resolve, reject) => {
    const options = {
      hostname: 'localhost',
      port: 11434,
      path: '/api/tags',
      method: 'GET'
    };

    const req = http.request(options, (res) => {
      let data = '';

      res.on('data', (chunk) => {
        data += chunk;
      });

      res.on('end', () => {
        try {
          const tags = JSON.parse(data);
          if (tags && Array.isArray(tags.models)) {
            resolve(tags);
          } else {
            reject(new Error('Ollama 服务响应格式错误'));
          }
        } catch (e) {
          reject(new Error('Ollama 服务响应解析失败'));
        }
      });
    });

    req.on('error', (error) => {
      console.error('Ollama 服务检查错误:', error);
      reject(new Error('Ollama 服务未运行，请先启动 Ollama'));
    });

    req.end();
  });
}

// 检查 Ollama 服务状态
async function checkOllamaService() {
  try {
    // 检查服务是否运行并获取模型列表
    const tags = await checkOllamaAPI();

    // 检查模型是否已下载
    const hasModel = tags.models.some(model =>
      model.name === 'deepseek-r1:1.5b' ||
      model.name === 'deepseek-r1' ||
      model.name.startsWith('deepseek-r1:')
    );

    if (!hasModel) {
      throw new Error('deepseek-r1:1.5b 模型未找到，请先下载模型');
    }

    return true;
  } catch (error) {
    throw error;
  }
}

// 添加健康检查接口
app.get('/health', async (req, res) => {
  try {
    await checkOllamaService();
    res.json({
      status: 'ok',
      ollama: 'running',
      model: 'deepseek-r1:1.5b ready'
    });
  } catch (error) {
    console.error('健康检查失败:', error);
    res.status(503).json({
      status: 'error',
      message: error.message,
      details: '请确保已执行以下步骤：\n1. 运行 Ollama 服务\n2. 执行 ollama pull deepseek-r1:1.5b 下载模型'
    });
  }
});

// 启动时检查服务状态
async function checkServiceOnStartup() {
  try {
    await checkOllamaService();
    console.log('✅ Ollama 服务正常运行');
    console.log('✅ deepseek-r1:1.5b 模型已就绪');
  } catch (error) {
    console.error('❌ 服务检查失败:', error.message);
    console.log('\n请按以下步骤操作:');
    console.log('1. 打开新的命令行窗口');
    console.log('2. 运行 ollama serve 启动服务');
    console.log('3. 运行 ollama pull deepseek-r1:1.5b 下载模型');
    process.exit(1);
  }
}

// 生成接口
app.post('/generate', async (req, res) => {
  const prompt = req.body.prompt || ''; // 用户输入的提示词
  const scene = req.body.scene || 'default'; // 场景参数，默认为default
  console.log('收到请求:', prompt, '场景:', scene);

  try {
    await checkOllamaService();
    console.log('Ollama 服务检查通过，开始调用模型...');

    // const context = [''];
    // 组合增强后的提示词
    // const enhancedPrompt = `${context}\n\n基于以上背景知识，请回答：${prompt}`;
    // 使用流式响应
    const stream = await openai.chat.completions.create({
      model: 'deepseek-r1:1.5b',
      messages: [{ role: 'user', content: prompt }],
      stream: true,
      temperature: 0.7,  // 添加温度参数，控制响应的随机性
      max_tokens: 2000,  // 限制最大token数
    });

    // 设置响应头
    res.setHeader('Content-Type', 'text/event-stream');
    res.setHeader('Cache-Control', 'no-cache');
    res.setHeader('Connection', 'keep-alive');

    let fullResponse = '';
    let isFirstChunk = true;

    // 处理流式响应
    for await (const chunk of stream) {
      const content = chunk.choices[0]?.delta?.content || '';
      if (content) {
        // 过滤掉<think>标签
        const filteredContent = content.replace(/<think>|<\/think>/g, '').trim();
        if (filteredContent) {
          fullResponse += filteredContent;
          // 发送数据块
          res.write(`data: ${JSON.stringify({
            response: filteredContent
              .replace(/\n/g, '\\n')  // 转义换行符
              .replace(/"/g, '\\"'), // 转义双引号
            status: 'streaming',
            isFirstChunk: isFirstChunk
          })}\n\n`);
          isFirstChunk = false;
        }
      }
    }

    // 根据场景选择推荐提示词
    const scenePrompts = recommendPrompts[scene] || recommendPrompts.default;

    // 发送完成信号时添加推荐提示词
    res.write(`data: ${JSON.stringify({
      response: fullResponse,
      status: 'complete',
      // recommendPrompts: scenePrompts // 根据场景返回对应的推荐提示词
    })}\n\n`);
    res.end();

  } catch (error) {
    console.error('服务错误:', error);
    res.status(503).json({
      error: 'service_error',
      message: error.message
    });
  }
});

// 处理 404
app.use((req, res) => {
  console.log('404 请求:', req.method, req.url);  // 添加日志
  res.status(404).json({ error: '接口不存在' });
});

// 启动服务器
const PORT = 8000;
app.listen(PORT, '0.0.0.0', async () => {
  console.log(`正在检查 Ollama 服务状态...`);
  await checkServiceOnStartup();
  console.log(`\n服务器运行在 http://localhost:${PORT}`);
});
